package com.fin.zw.aiqas.service;

import com.fin.zw.aiqas.entity.QResource;
import com.fin.zw.aiqas.entity.QRoleInfo;
import com.fin.zw.aiqas.entity.Resource;
import com.fin.zw.aiqas.entity.RoleInfo;
import com.fin.zw.aiqas.enums.ResourceType;
import com.fin.zw.aiqas.model.data.ResourceModel;
import com.fin.zw.aiqas.model.request.ResourceRequest;
import com.fin.zw.aiqas.model.response.ResourceResponse;
import com.fin.zw.aiqas.model.session.SessionModel;
import com.fin.zw.aiqas.repository.ResourceRepository;
import com.fin.zw.aiqas.repository.RoleInfoRepository;
import com.fin.zw.aiqas.util.BadRequestException;
import com.fin.zw.aiqas.util.BeanUtil;
import com.querydsl.core.BooleanBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.ListUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service("resourceService")
public class ResourceService {

    private static final Logger log = LoggerFactory.getLogger(ResourceService.class);

    @Autowired
    private ResourceRepository resourceRepository;

    @Autowired
    private RoleInfoRepository roleInfoRepository;

    @Autowired
    private CommonService commonService;

    /**
     * 查询所有菜单信息（分页）
     * @param pageable
     * @param request
     * @return
     */
    public Page<Resource> queryResourceAll(Pageable pageable,Resource request){
        BooleanBuilder builder = new BooleanBuilder();
        QResource qResource = QResource.resource;
        if(request.getName() != null){
            builder.and(qResource.name.eq(request.getName()));
        }
        if(request.getType() != null){
            builder.and(qResource.type.ne(request.getType()));
        }
        Page<Resource> page = resourceRepository.findAll(builder,pageable);
        return page;
    }

    /**
     * 查询所有的菜单信息
     * @return
     */
    public List<Resource> getResourceList(SessionModel sessionModel){
//        if(commonService.whetherAdmin(sessionModel)){
            return resourceRepository.findAll();
//        }else{
//            List<Resource> list = sessionModel.getResources();
//            return list;
//        }
    }

    public ResourceResponse getResourceResponses(SessionModel sessionModel) {
        ResourceResponse response = new ResourceResponse();
        Sort sort = new Sort(Sort.Direction.ASC, "sort");
        List<Resource> list = resourceRepository.findAll(sort);
        List<Resource> directories = list.stream().filter(resource -> resource.getType().equals(ResourceType.DIRECTORY)).collect(Collectors.toList());
        List<Resource> menus = list.stream().filter(resource -> resource.getType().equals(ResourceType.MENU)).collect(Collectors.toList());
        List<Resource> controls = list.stream().filter(resource -> resource.getType().equals(ResourceType.CONTROL)).collect(Collectors.toList());
        response.setDirectories(directories);
        response.setMenus(menus);
        response.setControls(controls);
        return response;
    }

    /**
     * 菜单的添加
     * @param resource
     */
    public void createResource(Resource resource){
        resourceRepository.save(resource);
    }

    /**
     * 菜单的修改
     * @param resource
     */
    public void updateResource(Resource resource, SessionModel sessionModel) {
        Optional<Resource> optional = resourceRepository.findById(resource.getId());
        if(!optional.isPresent()){
            log.info("修改菜单信息不存在");
            throw new BadRequestException("", "修改菜单信息不存在");
        }
        Resource res = optional.get();
        BeanUtil.copyProperties(resource, res);
        res.setUpdateUserId(sessionModel.getUserId());
        res.setUpdateRealName(sessionModel.getUserName());
        res.setUpdateTime(new Date());
        resourceRepository.save(res);
    }


    /**
     * 修改菜单名称
     *
     * @param resource
     * @param sessionModel
     */
    public void updateResourceName(ResourceModel resource, SessionModel sessionModel) {
        Optional<Resource> optional = resourceRepository.findById(resource.getId());
        if (!optional.isPresent()) {
            log.info("修改菜单信息不存在");
            throw new BadRequestException("", "修改菜单信息不存在");
        }
        Resource res = optional.get();
        res.setName(resource.getName());
        res.setUpdateUserId(sessionModel.getUserId());
        res.setUpdateRealName(sessionModel.getUserName());
        res.setUpdateTime(new Date());
        resourceRepository.save(res);
    }

    /**
     * 菜单的删除
     * @param id
     */
    public void deleteResourceById(Long id){
        Optional<Resource> optional = resourceRepository.findById(id);
        if(!optional.isPresent()){
            log.info("删除菜单信息不存在");
            throw new BadRequestException("", "删除菜单信息不存在");
        }
        Resource resource = optional.get();

        Iterator<Resource> iterator = resourceRepository.findAll(QResource.resource.parentId.eq(id)).iterator();
        if(iterator.hasNext()){
            log.info("菜单下存在子菜单，不允许删除");
            throw new BadRequestException("", "菜单下存在子菜单，不允许删除");
        }
        Iterator<RoleInfo> roleInfoIterator = roleInfoRepository.findAll(QRoleInfo.roleInfo.resources.contains(resource)).iterator();
        if(roleInfoIterator.hasNext()){
            log.info("该菜单已经被角色绑定，请先解绑");
            throw new BadRequestException("", "该菜单已经被角色绑定，请先解绑");
        }
        resourceRepository.delete(resource);
    }


    /**
     * 调整资源的顺序
     *
     * @param request
     * @param sessionModel
     */
    public void moveResource(ResourceRequest request, SessionModel sessionModel) {
        if (!ListUtils.isEmpty(request.getData())) {
            List<Resource> list = new ArrayList<>();
            Integer index = 1;
            for (ResourceModel resourceModel : request.getData()) {
                Optional<Resource> optional = resourceRepository.findById(resourceModel.getId());
                if (!optional.isPresent()) {
                    log.info("调整的资源信息不存在");
                    throw new BadRequestException("", "调整的资源信息不存在");
                }
                Resource resource = optional.get();
                resource.setSort(index);
                resource.setUpdateRealName(sessionModel.getUserName());
                resource.setUpdateUserId(sessionModel.getUserId());
                resource.setUpdateTime(new Date());
                index++;
                list.add(resource);
            }
            resourceRepository.saveAll(list);
        }
    }
}
